#region

using System.Collections.Generic;
using DomainModel.Domain.Model;
using DomainModel.Utils;
using NHibernate;

#endregion

namespace DomainModel.Infrastructure.Persistence
{
    public abstract class BaseRepository<TEntity, TPk> : IRepository<TEntity, TPk>
        where TEntity : class
    {
        private readonly ISession _session;
        private readonly string _sequenceName;

        protected BaseRepository(ISession session, IApplicationConfig applicationConfig)
        {
            _session = session;
            _sequenceName = applicationConfig.MainSequenceName;
        }

        protected ISession Session
        {
            get { return _session; }
        }
        
        protected ICriteria BuildCriteria()
        {
            return Session.CreateCriteria(typeof (TEntity));
        }
        
        #region IRepository<TEntity,TPk> Members

        public virtual TEntity GetById(TPk id)
        {
            return Session.Get<TEntity>(id);
        }

        public virtual IList<TEntity> GetAll()
        {
            return BuildCriteria().List<TEntity>();
        }

        public virtual TEntity Store(TEntity entity)
        {
            using (ITransaction transaction = Session.BeginTransaction())
            {
                Session.SaveOrUpdate(entity);

                transaction.Commit();
            }
            return entity;
        }

        public virtual void Delete(TEntity entity)
        {
            using (ITransaction transaction = Session.BeginTransaction())
            {
                Session.Delete(entity);

                transaction.Commit();
            }
        }

        #endregion

        protected int NextIntFromSeq()
        {
            long result = (long) Session.CreateSQLQuery(string.Format("select nextval('{0}')", _sequenceName))
                             .UniqueResult();

            return (int) result;
        }
    }
}